/*
 Generate a Message Authentication Code
 */
package code;

import java.io.*;
import java.security.*;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Set;
import java.util.StringTokenizer;

import javax.crypto.*;
import javax.xml.parsers.*;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;



import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;



public class MessageAuthenticationCode {
	//algorithm "HmacMD5" "HmacSHA1"

	private SecretKey key;
	public Mac mac;
	public String file;
	public byte[]  calcmac;
	public String algorithm;
	public String keyalias;
	public HashMap logmac;
	public String digestB64;

	public void generateKey(String algorithm){
		try {
			KeyGenerator keyGen = KeyGenerator.getInstance(algorithm);
			key = keyGen.generateKey();
			this.algorithm=algorithm;
		} catch (Exception e) {
		}
	}
	public void calculateMAC(String algorithm, SecretKey key, String keyalias, String file){
		try {
			this.algorithm=algorithm;
			this.file=file;
			this.keyalias=keyalias;
			System.out.println("calculate mac key alias:"+this.keyalias);
			mac = Mac.getInstance(algorithm);
			mac.init(key);
			FileInputStream inFile = new FileInputStream(file);

			byte[] input = new byte[64];
			int bytesRead;

			while ((bytesRead = inFile.read(input)) != -1)
			{		
				mac.update(input, 0, bytesRead);

			}


			inFile.close();

			System.out.println( "\nMAC: " );
			calcmac= mac.doFinal();
			 digestB64 = new sun.misc.BASE64Encoder().encode(calcmac);
			System.out.println(digestB64);

		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	public String parsefilepath(){
		String filename=null;
		StringTokenizer st= new StringTokenizer(file, File.separator);
		while(st.hasMoreTokens()){
			filename=st.nextToken();
		}
		return filename;
	}
	public void store(){
		read();
		
		String log=keyalias+","+digestB64+","+algorithm+","+new Date()+","+file;
		System.out.println("store key alias:"+keyalias);
		String filename=parsefilepath();
		logmac.put(filename, log);

		
			DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
			DocumentBuilder documentBuilder;
			try {
				documentBuilder = documentBuilderFactory.newDocumentBuilder();

				Document document = documentBuilder.newDocument();

				Element rootElement = document.createElement("mac");
				document.appendChild(rootElement);


				Set set=logmac.keySet();
				Iterator i= set.iterator();
				String s;
				System.out.println(set);
				while(i.hasNext()){
					s=(String)i.next();
					Element em = document.createElement(s);
					em.appendChild(document.createTextNode((String)logmac.get(s)));
					rootElement.appendChild(em);
				}
				TransformerFactory transformerFactory = TransformerFactory.newInstance();
				Transformer transformer = transformerFactory.newTransformer();
				DOMSource source = new DOMSource(document);
				StreamResult result =  new StreamResult(System.getProperty("user.home") + File.separator + "Atoco" + File.separator + "mac.xml");
				transformer.transform(source, result);
			} catch (Exception e) {
				e.printStackTrace();
			}
		

	}



	public void read(){
		try{
			File f= new File(System.getProperty("user.home") + File.separator + "Atoco" + File.separator + "mac.xml");
			logmac=new HashMap();
			if(f.exists()){
				DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();   
				DocumentBuilder parser = factory.newDocumentBuilder();
				Document d= parser.parse(System.getProperty("user.home") + File.separator + "Atoco" + File.separator + "mac.xml");
				Element root = d.getDocumentElement();   
				Node n = root.getFirstChild();  
				if (n != null){  

					do {   
						if (n.getNodeType() == Node.ELEMENT_NODE){   
							logmac.put(n.getNodeName(), n.getFirstChild().getNodeValue());
						}   
					}while ((n=n.getNextSibling()) != null );   
				}   
			}

		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	public void delete(String file){
		read();
		System.out.println("alias: "+keyalias);
		System.out.println(logmac);
		if(logmac.containsKey(file)){
			logmac.remove(file);
			System.out.println("var file buldum");
			DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
			DocumentBuilder documentBuilder;
			try {
				documentBuilder = documentBuilderFactory.newDocumentBuilder();

				Document document = documentBuilder.newDocument();

				Element rootElement = document.createElement("mac");
				document.appendChild(rootElement);


				Set set=logmac.keySet();
				Iterator i= set.iterator();
				String s;
				while(i.hasNext()){
					s=(String)i.next();
					Element em = document.createElement(s);
					em.appendChild(document.createTextNode((String)logmac.get(s)));
					rootElement.appendChild(em);
				}
				TransformerFactory transformerFactory = TransformerFactory.newInstance();
				Transformer transformer = transformerFactory.newTransformer();
				DOMSource source = new DOMSource(document);
				StreamResult result =  new StreamResult(System.getProperty("user.home") + File.separator + "Atoco" + File.separator + "mac.xml");
				transformer.transform(source, result);
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		
	}

	public static void main (String[] args){



		MessageAuthenticationCode mac= new MessageAuthenticationCode();
		mac.generateKey("HmacSHA1");
		SecretKey key=mac.getKey();
		mac.calculateMAC("HmacSHA1", key, "alias2", "C:\\Documents and Settings\\Nil Kural\\Desktop\\driving.txt");
		mac.store();
		//mac.delete("alias9");

//java util separator char


	}
	public SecretKey getKey() {
		return key;
	}
	public void setKey(SecretKey key) {
		this.key=key;
	}
}